// SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
// SPDX-License-Identifier: Mulan PSL v2
package com.geniusai.aip.auth.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.geniusai.aip.auth.config.ExternalConfig;
import com.geniusai.aip.auth.config.InitialImageConfig;
import com.geniusai.aip.auth.constants.LoadConstants;
import com.geniusai.aip.auth.domain.InitialImageDO;
import com.geniusai.aip.auth.domain.ResourceCustomVGpuDO;
import com.geniusai.aip.auth.domain.ResourceCustomVGpuRequest;
import com.geniusai.aip.auth.domain.UserDO;
import com.geniusai.aip.auth.domain.convertor.IdConverter;
import com.geniusai.aip.auth.exception.AuthLoginException;
import com.geniusai.aip.auth.exception.AuthLoginExceptionEnum;
import com.geniusai.aip.auth.mapper.ResourceCustomVGpuMapper;
import com.geniusai.aip.auth.mapper.UserMapper;
import com.geniusai.aip.auth.service.ResourceCustomVGpuService;
import com.geniusai.aip.auth.service.UserService;
import com.geniusai.aip.feature.common.utils.StringUtils;
import com.geniusai.aip.feature.common.web.utils.UrlUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author hml14563
 * @date 2021/4/15
 */
@RequiredArgsConstructor
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class InitData implements ApplicationListener<ApplicationReadyEvent> {
    @Autowired
    private ExternalConfig externalConfig;
    @Autowired
    private InitialImageConfig initialImageConfig;
    @Autowired
    private UserMapper userdomapper;
    @Autowired
    private UserService userService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ResourceCustomVGpuService resourceCustomVGpuService;

    /**
     * 公共镜像的镜像tag
     */
    private static final String[] IMAGES_TAGS = { "public_notebook" };
    /**
     * 公共镜像的type
     */
    private static final Integer TYPE = 1;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        int adminCount = userdomapper.selectCount(new QueryWrapper<UserDO>().eq("username", externalConfig.getAdminName()));
        if (adminCount == 0) {
            initUser(externalConfig.getAdminName(), externalConfig.getAdminPwd());
            log.info("admin用户创建完毕");
        }

        log.info("初始用户检查完毕,即将开始auth-login服务");
    }

    private void initUser(String username, String password) {
        UserDO user = new UserDO();
        user.setEmail(StringUtils.getUserEmail(username));
        user.setUsername(username);
        user.setPassword(ArrayUtils.toObject(password.getBytes()));
        user.setRole(LoadConstants.ADMIN);
        user.setUserId(IdConverter.username2id(username));
        user.setCpuNum((float) externalConfig.getCpuNum());
        user.setVgpuMemory(externalConfig.getMemorySize());
        user.setMemorySize(externalConfig.getMemorySize());
        user.setVolumeSize(externalConfig.getStorageSize());
        user.setS3AccessKey(username);
        user.setS3SecretKey(UUID.randomUUID().toString());
        user.setIsFirstLogin(1);
        userService.createUser(user);
        // 创建管理员时初始化公共镜像
        createInitialImage(user.getUserId());
        // 创建管理员时预定义vGpu规格
        resourceCustomVGpuService.customVGpuMemorySize();
    }


    private void addInitialImage(String userId, InitialImageDO initialImageDO) {
        try {
            restTemplate.postForObject(
                    UrlUtils.createUrl(
                            externalConfig.getServiceManage(),
                            externalConfig.getServiceManagePort(), "deploy/v1/users/" + userId + "/images"
                    ), initialImageDO, InitialImageDO.class
            );
        } catch (Exception e) {
            throw new AuthLoginException(AuthLoginExceptionEnum.ADD_INITIALIMAGE_ERROR, e);
        }
    }

    private void createInitialImage(String userId) {
        // 创建管理员时初始化公共镜像
        List<InitialImageDO> images = initialImageConfig.getPublicImages();
        images.forEach(image -> {
            InitialImageDO initialImageDO = new InitialImageDO(image.getAddress(), image.getDescription(), TYPE, IMAGES_TAGS);
            addInitialImage(userId, initialImageDO);
        });
    }

}
